package com.ketti.team;

import android.content.Context;
import android.graphics.Color;
import android.text.InputFilter;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class SourceView extends RelativeLayout {
	
	private NewEditText newSourceView;
	private LinearLayout searchBoxLayout;
	private Button searchBoxButton;
	private EditText searchBoxEdit;
	private String preSearchString = "";
	private int preSearchStart = 0;
	private int preSearchCount = 0;
	private InputMethodManager iputMethodManager;
	
	// This is keyword to highlight
	private final String[] keyWordList = new String[] {
			"abstract", "assert", "boolean", "break", "byte", 
			"case", "catch", "char", "class", "const",
			"continue", "default", "do", "double", "else", 
			"enum", "extends", "false", "final", "finally",
			"float", "for", "goto", "if", "implements",
            "import", "instanceof", "int", "interface", "long", 
            "native", "new", "null", "package", "private", "protected",
            "public", "return", "short", "static", "strictfp",
            "super", "switch", "synchronized", "this", "throw", "throws",
            "true", "transient", "try", "void", "volatile", "while"
            };
	
	private final String[] CommentList = new String[] {"cool", "/", "*"};
	
	private InputFilter keyWordInputFilter, CommentInputFilter;	

	public SourceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public SourceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	public SourceView(Context context) {
		super(context);
		String inflaterService = Context.LAYOUT_INFLATER_SERVICE;
		LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(inflaterService);
		layoutInflater.inflate(R.layout.source_view, this, true);		
		
		newSourceView 	= (NewEditText) 	findViewById(R.id.source_editor);
		searchBoxLayout = (LinearLayout) 	findViewById(R.id.search_box_layout);
		searchBoxButton = (Button) 			findViewById(R.id.search_box_button);
		searchBoxEdit	= (EditText)		findViewById(R.id.search_box_edit);
		
		newSourceView.setSearchBoxLayout(searchBoxLayout);
		newSourceView.setSearchBoxEdit(searchBoxEdit);		
		newSourceView.setText(R.string.test_string);
		newSourceView.setTextSize(Setting.getmFontSize());
		newSourceView.setGravity(Gravity.TOP);
//		newSourceView.setScrollContainer(true);
		newSourceView.setHorizontallyScrolling(true);
		
		setInitailKeyWordFilter(newSourceView, keyWordList);						
		setKeyWordInputFilter();
		setCommentInputFilter();
		newSourceView.setFilters(new InputFilter[] {keyWordInputFilter, CommentInputFilter});
		
		searchBoxButton.setTextSize(Setting.getmFontSize());
		searchBoxEdit.setTextSize(Setting.getmFontSize());
		
		hookUpButton();				
	}
	
	/**
	 * connect buttons in this view to setOnClickListener 
	 **/
	private void hookUpButton() {
		searchBoxButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {				
				String searchBoxEditString = searchBoxEdit.getText().toString();
				
				// we can't expect when user edit the source in newSourceView, therefore we have to
				// bring the source whenever search button being clicked
				String newSourceViewString = newSourceView.getText().toString();
				
				// hide soft keyboard
				iputMethodManager.hideSoftInputFromWindow(newSourceView.getWindowToken(), 0);
				
				// if there's no string in searchBoxEdit, show a toast message				
				if(searchBoxEdit.length() == 0){
					Toast toast = Toast.makeText(getContext(), "Please enter some text to search", Toast.LENGTH_SHORT);
					toast.setGravity(Gravity.TOP, 0, 150);
					toast.show();
				
				}else{
					
					// if the searchBoxEdit's string is different from previous result, start from beginning of source					
					if(!(searchBoxEditString.equals(preSearchString))){
						preSearchString	= searchBoxEditString;
						preSearchStart	= newSourceViewString.indexOf(preSearchString);
						preSearchCount	= preSearchString.length();												
						
						// if there's a match, select it										
						if(preSearchStart != -1)
							Selection.setSelection(newSourceView.getText(), preSearchStart, preSearchStart + preSearchCount);
						
						// no match, show a toast message
						else{
							Toast toast = Toast.makeText(getContext(), "No matches", Toast.LENGTH_SHORT);
							toast.setGravity(Gravity.TOP, 0, 100);
							toast.show();
						}
					
					// if the searchBoxEdit's string is same as previous result, starts at next to the previous result
					}else {
						preSearchStart = newSourceViewString.indexOf(preSearchString, preSearchStart + preSearchCount);
						
						// if there's no matches, start again
						if(preSearchStart == -1)
							preSearchStart = newSourceViewString.indexOf(preSearchString);
						
						Selection.setSelection(newSourceView.getText(), preSearchStart , preSearchStart  + preSearchCount);						
					}					
					newSourceView.requestFocus();
				}			
			}
		});
	}

	/**
	 * Setup keyword filter to highlight keyword in source. if user put 
	 * some keyword to EditText, this filter automatically change this word to red 
	 **/	
	 private void setKeyWordInputFilter() {
	    	keyWordInputFilter = new InputFilter() {
				
				@Override
				public CharSequence filter(CharSequence source, int start, int end,
						Spanned dest, int dstart, int dend) {
					for(String s : keyWordList)
					{
						if(s.equals(source.toString()))
						{						
							SpannableString sp = new SpannableString(source);
							sp.setSpan(new ForegroundColorSpan(Color.RED), 0, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);						
							return sp;
						}
					}
					return source;
				}
			};
	}
	 
	 private void setCommentInputFilter(){
		 CommentInputFilter = new InputFilter() {
			
			@Override
			public CharSequence filter(CharSequence source, int start, int end,
					Spanned dest, int dstart, int dend) {				
				for(String s : CommentList)
				{
					if(s.equals(source.toString()))
					{												
						SpannableString sp = new SpannableString(source);
						sp.setSpan(new ForegroundColorSpan(Color.GREEN), 0, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);						
						return sp;
					}
				}
				return source;
			}
		};
	 }
	 
	/* Change keyword in initial source to red  */
	private void setInitailKeyWordFilter(NewEditText newSourceView,
			String[] keyWordList) {
		SpannableString source = new SpannableString(newSourceView.getText());
        
        for(String s : keyWordList){
        	if(source.toString().indexOf(s) != -1){
        		source.setSpan(new ForegroundColorSpan(Color.RED), source.toString().indexOf(s), source.toString().indexOf(s) + s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        	}
        }
        newSourceView.setText(source); 
	}
	
	/* get 'iputMethodManager' from activity  */
	public void setInputMethodManager(InputMethodManager imm){
		iputMethodManager = imm;
	}
}
